Implementasi Domainkeys.
Anton Rahmadi @31 Januari 2009
versi 1.4 GPL

Domainkeys (DKIMProxy dan dkfilter)
Catatan: 
Yahoo hanya mendukung dkfilter (out), dkfilter dan DKIM (in)
Gmail hanya mendukung DKIM (in), , dkfilter dan DKIM (out)
Tutorial ini:  dkfilter (in), dkfilter dan DKIM (out)


Buat user

	groupadd domainkeys
	useradd -s /bin/false -d /dev/null -g domainkeys domainkeys


Membuat direktori kerja

	mkdir /usr/local/domainkeys


Buat private dan public key

	cd /usr/local/domainkeys
	openssl genrsa -out private.key 1024
	openssl rsa -in private.key -pubout -out public.key
	chown domainkeys.domainkeys private.key
	chmod 600 private.key


Edit entri di DNS server / Hosting

	_domainkey.namadomain.ac.id        		IN TXT  “t=y; o=~;”
	selector1._domainkey.namadomain.ac.id	IN TXT "k=rsa; p=ISI_DARI_PUBLIC_KEY;"


Instalasi modul-modul PERL yang dibutuhkan

	perl -MCPAN -e'CPAN::Shell->install("Crypt::OpenSSL::RSA")'
	perl -MCPAN -e'CPAN::Shell->install("Digest::SHA")'
	perl -MCPAN -e'CPAN::Shell->install("Digest::SHA1")'
	perl -MCPAN -e'CPAN::Shell->install("Error")'
	perl -MCPAN -e'CPAN::Shell->install("Mail::Address")'
	perl -MCPAN -e'CPAN::Shell->install("MIME::Base64")'
	perl -MCPAN -e'CPAN::Shell->install("Net::DNS")'
	perl -MCPAN -e'CPAN::Shell->install("Net::Server")'
	perl -MCPAN -e'CPAN::Shell->install("Test::More")'
	perl -MCPAN -e'CPAN::Shell->install("Text::Wrap")'
	perl -MCPAN -e'CPAN::Shell->install("Mail::DomainKeys")'


Instalasi dkfilter versi 0.11 (last update: 22Jan2009)

	cd /usr/local/src
	wget -c http://jason.long.name/dkfilter/dkfilter-0.11.tar.gz
	tar -xzvf dkfilter-0.11.tar.gz
	cd dkimproxy-1.1
	make clean
	make tidy
	./configure --prefix=/usr/local/domainkeys/dkfilter
	make install


Instalasi Mail-DKIM versi 0.32 (last update: 21Jan2009)

	cd /usr/local/src
	wget -c http://search.cpan.org/CPAN/authors/id/J/JA/JASLONG/Mail-DKIM-0.32.tar.gz
	tar -xzvf Mail-DKIM-0.32.tar.gz
	cd Mail-DKIM-0.32
	make clean
	make tidy
	perl Makefile.PL
	make
	make test
	make install


Instalasi dkimproxy versi 1.1 (last update: 21Jan2009)

	cd /usr/local/src/
	wget -c http://downloads.sourceforge.net/dkimproxy/dkimproxy-1.1.tar.gz
	tar -xzvf dkimproxy-1.1.tar.gz
	cd dkimproxy-1.1
	make clean
	make tidy
	./configure --prefix=/usr/local/domainkeys/dkimproxy
	make install


Membuat script /usr/local/domainkeys/dkfilter-in

	#!/bin/bash
	#--- Generic Service Start/Stop Script
	#--- Anton Rahmadi @27Jan2009

	#--- dkfilter.in
	SERVICENAME=dkfilter.in
	SERVICEFILE=/usr/local/domainkeys/bin/dkfilter.in  
	SERVICEPID=/var/run/dkfilter.in.pid
	SERVICECONFIG="--user domainkeys --group domainkeys --daemonize \
		--pidfile=$SERVICEPID 127.0.0.1:10023 127.0.0.1:10024"

	#--- Optional configuration
	SLEEPVALUE=2  #put higher number for slower CPU 

	#--- Non configurable 
	checkservice() {
		if [ ! -f "$SERVICEFILE" ]; then
		 echo "$SERVICEFILE: 	NOT FOUND"
		 exit 0
		fi
	}

	startservice() {
		if [ -e "$SERVICEPID" ]; then
		echo "$SERVICENAME:		ALREADY STARTED"
		exit 0
		else
		$SERVICEFILE $SERVICECONFIG
		fi	
	}

	stopservice() {
		if [ -e "$SERVICEPID" ]; then
		kill `cat $SERVICEPID` 
		rm -f $SERVICEPID
		else
		echo "$SERVICENAME:		ALREADY STOP"
		exit 0
		fi
	}

	checkstatus() {
		if [ -e "$SERVICEPID" ]; then
		    echo "$SERVICENAME:		STARTED"
		else
		    echo "$SERVICENAME:		STOP"
		fi
	}

	checkservice
	case "$1" in
		'start')
		startservice	
		sleep $SLEEPVALUE
		    checkstatus
		;;
		'stop')
		stopservice
		checkstatus
		;;
		'restart')
		$0 stop
		$0 start
		;;
		'status')
		checkstatus	
		;;
		*)
		echo "Usage $0 {start|stop|restart|status}"
		;;
	esac


Membuat script /usr/local/domainkeys/dkfilter-out

	#!/bin/bash
	#--- Generic Service Start/Stop Script
	#--- Anton Rahmadi @27Jan2009

	#--- dkfilter.out
	SERVICENAME=dkfilter.out
	SERVICEFILE=/usr/local/domainkeys/bin/dkfilter.out  
	SERVICEPID=/var/run/dkfilter.out.pid
	SERVICECONFIG="--user domainkeys --group domainkeys --daemonize \
		--pidfile=$SERVICEPID --keyfile=/usr/local/domainkeys/private.key \
		--selector=selector1  --domain=namadomain.ac.id,subdomain.namadomain.ac.id \
		--method=nofws 127.0.0.1:10029 127.0.0.1:10030"

	#--- Optional configuration
	SLEEPVALUE=2  #put higher number for slower CPU 

	#--- Non configurable 
	checkservice() {
		if [ ! -f "$SERVICEFILE" ]; then
		 echo "$SERVICEFILE: 	NOT FOUND"
		 exit 0
		fi
	}

	startservice() {
		if [ -e "$SERVICEPID" ]; then
		echo "$SERVICENAME:		ALREADY STARTED"
		exit 0
		else
		$SERVICEFILE $SERVICECONFIG
		fi	
	}

	stopservice() {
		if [ -e "$SERVICEPID" ]; then
		kill `cat $SERVICEPID` 
		rm -f $SERVICEPID
		else
		echo "$SERVICENAME:		ALREADY STOP"
		exit 0
		fi
	}

	checkstatus() {
		if [ -e "$SERVICEPID" ]; then
		    echo "$SERVICENAME:		STARTED"
		else
		    echo "$SERVICENAME:		STOP"
		fi
	}

	checkservice
	case "$1" in
		'start')
		startservice	
		sleep $SLEEPVALUE
		    checkstatus
		;;
		'stop')
		stopservice
		checkstatus
		;;
		'restart')
		$0 stop
		$0 start
		;;
		'status')
		checkstatus	
		;;
		*)
		echo "Usage $0 {start|stop|restart|status}"
		;;
	esac


Membuat script /usr/local/dkim/dkim-in

	#!/bin/bash
	#--- Generic Service Start/Stop Script
	#--- Anton Rahmadi @27Jan2009

	#--- dkimproxy.in
	SERVICENAME=dkimproxy.in
	SERVICEFILE=/usr/local/dkim/bin/dkimproxy.in  
	SERVICEPID=/var/run/dkimproxy.in.pid
	SERVICECONFIG="--user domainkeys --group domainkeys --pidfile=$SERVICEPID \
		--daemonize --reject-fail 127.0.0.1:10025 127.0.0.1:10026"

	#--- Optional configuration
	SLEEPVALUE=2  #put higher number for slower CPU 

	#--- Non configurable 
	checkservice() {
		if [ ! -f "$SERVICEFILE" ]; then
		 echo "$SERVICEFILE: 	NOT FOUND"
		 exit 0
		fi
	}

	startservice() {
		if [ -e "$SERVICEPID" ]; then
		echo "$SERVICENAME:		ALREADY STARTED"
		exit 0
		else
		$SERVICEFILE $SERVICECONFIG
		fi	
	}

	stopservice() {
		if [ -e "$SERVICEPID" ]; then
		kill `cat $SERVICEPID` 
		rm -f $SERVICEPID
		else
		echo "$SERVICENAME:		ALREADY STOP"
		exit 0
		fi
	}

	checkstatus() {
		if [ -e "$SERVICEPID" ]; then
		    echo "$SERVICENAME:		STARTED"
		else
		    echo "$SERVICENAME:		STOP"
		fi
	}

	checkservice
	case "$1" in
		'start')
		startservice	
		sleep $SLEEPVALUE
		    checkstatus
		;;
		'stop')
		stopservice
		checkstatus
		;;
		'restart')
		$0 stop
		$0 start
		;;
		'status')
		checkstatus	
		;;
		*)
		echo "Usage $0 {start|stop|restart|status}"
		;;
	esac


::ALTERNATIF 1 (cara cepat)::
Membuat script /usr/local/dkim/dkim-out

	#!/bin/bash
	#--- Generic Service Start/Stop Script
	#--- Anton Rahmadi @27Jan2009

	#--- dkimproxy.out
	SERVICENAME=dkimproxy.out
	SERVICEFILE=/usr/local/dkim/bin/dkimproxy.out  
	SERVICEPID=/var/run/dkimproxy.out.pid
	SERVICECONFIG="--user domainkeys --group domainkeys --pidfile=$SERVICEPID \
		--daemonize --signature=dkim --signature=domainkeys \
		--keyfile=/usr/local/dkim/private.key --selector=selector1  \
		--domain=namadomain.ac.id,subdomain.namadomain.ac.id --method=simple \
		127.0.0.1:10027 127.0.0.1:10028"

	#--- Optional configuration
	SLEEPVALUE=2  #put higher number for slower CPU 

	#--- Non configurable 
	checkservice() {
		if [ ! -f "$SERVICEFILE" ]; then
		 echo "$SERVICEFILE: 	NOT FOUND"
		 exit 0
		fi
	}

	startservice() {
		if [ -e "$SERVICEPID" ]; then
		echo "$SERVICENAME:		ALREADY STARTED"
		exit 0
		else
		$SERVICEFILE $SERVICECONFIG
		fi	
	}

	stopservice() {
		if [ -e "$SERVICEPID" ]; then
		kill `cat $SERVICEPID` 
		rm -f $SERVICEPID
		else
		echo "$SERVICENAME:		ALREADY STOP"
		exit 0
		fi
	}

	checkstatus() {
		if [ -e "$SERVICEPID" ]; then
		    echo "$SERVICENAME:		STARTED"
		else
		    echo "$SERVICENAME:		STOP"
		fi
	}

	checkservice
	case "$1" in
		'start')
		startservice	
		sleep $SLEEPVALUE
		    checkstatus
		;;
		'stop')
		stopservice
		checkstatus
		;;
		'restart')
		$0 stop
		$0 start
		;;
		'status')
		checkstatus	
		;;
		*)
		echo "Usage $0 {start|stop|restart|status}"
		;;
	esac


::ALTERNATIF 2 (Lebih baik)::
Membuat konfigurasi /etc/postfix/dkim.conf

	#signature ganda namadomain.ac.id dan subdomain.namadomain.ac.id mail
	namadomain.ac.id domainkeys(a=rsa-sha1,c=nofws, key=/usr/local/dkim/private.key, s=selector1), dkim(a=rsa-sha256,c=relaxed, key=/usr/local/dkim/private.key, s=selector1)
	subdomain.namadomain.ac.id domainkeys(a=rsa-sha1,c=nofws, key=/usr/local/dkim/private.key, s=selector1), dkim(a=rsa-sha1,c=relaxed, key=/usr/local/dkim/private.key, s=selector1)


Membuat script /usr/local/dkim/dkim-out dengan konfigurasi pada /etc/postfix/dkim.conf

	#!/bin/bash
	#--- Generic Service Start/Stop Script
	#--- Anton Rahmadi @27Jan2009

	#--- dkimproxy.out
	SERVICENAME=dkimproxy.out
	SERVICEFILE=/usr/local/dkim/bin/dkimproxy.out  
	SERVICEPID=/var/run/dkimproxy.out.pid
	SERVICECONFIG="--user domainkeys --group domainkeys --pidfile=$SERVICEPID \
		--daemonize  --sender_map=/etc/postfix/dkim.conf \
		127.0.0.1:10027 127.0.0.1:10028"

	#--- Optional configuration
	SLEEPVALUE=2  #put higher number for slower CPU 

	#--- Non configurable 
	checkservice() {
		if [ ! -f "$SERVICEFILE" ]; then
		 echo "$SERVICEFILE: 	NOT FOUND"
		 exit 0
		fi
	}

	startservice() {
		if [ -e "$SERVICEPID" ]; then
		echo "$SERVICENAME:		ALREADY STARTED"
		exit 0
		else
		$SERVICEFILE $SERVICECONFIG
		fi	
	}

	stopservice() {
		if [ -e "$SERVICEPID" ]; then
		kill `cat $SERVICEPID` 
		rm -f $SERVICEPID
		else
		echo "$SERVICENAME:		ALREADY STOP"
		exit 0
		fi
	}

	checkstatus() {
		if [ -e "$SERVICEPID" ]; then
		    echo "$SERVICENAME:		STARTED"
		else
		    echo "$SERVICENAME:		STOP"
		fi
	}

	checkservice
	case "$1" in
		'start')
		startservice	
		sleep $SLEEPVALUE
		    checkstatus
		;;
		'stop')
		stopservice
		checkstatus
		;;
		'restart')
		$0 stop
		$0 start
		;;
		'status')
		checkstatus	
		;;
		*)
		echo "Usage $0 {start|stop|restart|status}"
		;;
	esac


Merubah permisi dari semua skrip rc.* di /usr/local/domainkeys/

	chmod 755 rc.*


Menjalankan semua skrip rc.* di /usr/local/domainkeys/

	/usr/local/domainkeys/rc.dkfilter-in start
	/usr/local/domainkeys/rc.dkfilter-out start
	/usr/local/domainkeys/rc.dkim-in start
	/usr/local/domainkeys/rc.dkim-out start

Melihat keaktifan domain key

	netstat -plan | grep tcpd
	tcp        0      0 127.0.0.1:10023         0.0.0.0:*               LISTEN     6639/perl           
	tcp        0      0 127.0.0.1:10025         0.0.0.0:*               LISTEN     6649/perl           
	tcp        0      0 127.0.0.1:10027         0.0.0.0:*               LISTEN     6650/perl           
	tcp        0      0 127.0.0.1:10029         0.0.0.0:*               LISTEN     6651/perl      


Apabila berhasil, maka masukkan eksekusi semua skrip rc.* ke rc.local

	cat "/usr/local/domainkeys/rc.dkfilter-in start" >> /etc/rc.d/rc.local
	cat "/usr/local/domainkeys/rc.dkfilter-out start" >> /etc/rc.d/rc.local
	cat "/usr/local/domainkeys/rc.dkim-in start" >> /etc/rc.d/rc.local
	cat "/usr/local/domainkeys/rc.dkim-out start" >> /etc/rc.d/rc.local


Backup /etc/postfix/master.cf

	cd /etc/postfix
	cp master.cf master.cf.nodomainkeys


Sesuaikan isi dari /etc/postfix/master.cf

	# a line below is commented to support domainkeys inbound -Arahmadi@20jan2009
	#smtp     inet  n       -       n       -       -       smtpd

	# begin ---- domainkeys implementation, ARahmadi @20Jan2009

	smtp      inet  n       -       n       -       -       smtpd
		#untuk cek signature dkfilter, atau
		#-o smtpd_proxy_filter=127.0.0.1:10023
		#untuk cek signature dkim
		-o smtpd_proxy_filter=127.0.0.1:10025	
		-o smtpd_client_connection_count_limit=10

	submission  inet  n     -       n       -       -       smtpd
		-o smtpd_etrn_restrictions=reject
		#apabila tidak mengimplementasikan SASL,atau
		-o smtpd_sasl_auth_enable=no	
		#apabila mengimplementasikan SASL
		#-o smtpd_sasl_auth_enable=yes
		-o content_filter=dkimsign:[127.0.0.1]:10027
		-o receive_override_options=no_address_mappings
		-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject

	#dkfilter.in 
	127.0.0.1:10024 inet n  -       n       -        -      smtpd
		-o content_filter =
		-o smtpd_authorized_xforward_hosts=127.0.0.0/8
		-o smtpd_client_restrictions=
		-o smtpd_helo_restrictions=
		-o smtpd_sender_restrictions=
		-o smtpd_recipient_restrictions=permit_mynetworks,reject
		-o smtpd_data_restrictions=
		-o mynetworks=127.0.0.0/8
		-o receive_override_options=no_unknown_recipient_checks

	#dkim.in 
	127.0.0.1:10026 inet n  -       n       -        -      smtpd
		-o content_filter =
		-o smtpd_authorized_xforward_hosts=127.0.0.0/8
		-o smtpd_client_restrictions=
		-o smtpd_helo_restrictions=
		-o smtpd_sender_restrictions=
		-o smtpd_recipient_restrictions=permit_mynetworks,reject
		-o smtpd_data_restrictions=
		-o mynetworks=127.0.0.0/8
		-o receive_override_options=no_unknown_recipient_checks

	#dkim.out, double signature: domainkeys, dkim
	dkimsign    unix  -       -       n       -       10      smtp
		-o smtp_send_xforward_command=yes
		-o smtp_discard_ehlo_keywords=8bitmime

	127.0.0.1:10028 inet  n  -      n       -       10      smtpd
		-o content_filter=
		-o receive_override_options=no_unknown_recipient_checks,no_address_mappings
		-o smtpd_helo_restrictions=
		-o smtpd_client_restrictions=
		-o smtpd_sender_restrictions=
		-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
		-o mynetworks=127.0.0.0/8
		-o smtpd_authorized_xforward_hosts=127.0.0.0/8

	# end ---- domainkeys implementation


Ubah konfigurasi di /etc/postfix/main.cf

	cd /etc/postfix
	vi main.cf

	---------------------perubahan isi main.cf----------------------
	127.0.0.1:10024_time_limit = 3600
	127.0.0.1:10026_time_limit = 3600
	127.0.0.1:10028_time_limit = 3600
	---------------------perubahan isi main.cf----------------------


Reload postfix

	postfix reload


Melihat keaktifan domainkey

	netstat -plan | grep tcpd
	tcp        0      0 127.0.0.1:10023         0.0.0.0:*               LISTEN     6639/perl           
	tcp        0      0 127.0.0.1:10025         0.0.0.0:*               LISTEN     6649/perl           
	tcp        0      0 127.0.0.1:10026         0.0.0.0:*               LISTEN     30205/master        
	tcp        0      0 0.0.0.0:587             0.0.0.0:*               LISTEN     30205/master        
	tcp        0      0 127.0.0.1:10027         0.0.0.0:*               LISTEN     6650/perl           
	tcp        0      0 127.0.0.1:10028         0.0.0.0:*               LISTEN     30205/master   
	tcp        0      0 127.0.0.1:10029         0.0.0.0:*               LISTEN     6651/perl           
	tcp        0      0 127.0.0.1:10030         0.0.0.0:*               LISTEN     30215/master   


Mengubah SMTP port dari mail klien menjadi 587,  BUKAN 25  atau gunakan NAT dari iptables

